<?php
/**
 * Created by PhpStorm.
 * User: yuanxr
 * Date: 2018/6/10
 * Time: 上午8:17
 */

namespace Utility\Encrypt;
/**********************************************************************************************************************
 * 动态对象功能
 * 
 * 1、DES（可逆加密解密）
 * 2、ET（效率测试）
 **********************************************************************************************************************/
/**********************************************************************************************************************
 * /DES：字符串加密解密类
 **********************************************************************************************************************/
class DES
{
    private $key;		// 任意位数的key字符串
    private $iv;		// iv只允许8位字符串

    /**
     * __construct
     */
    public function __construct()
    {
        $this->key = base64_encode('a25f+_4.fef)(Uf5');
        $this->iv = base64_encode('s#f!3=-s');
    }

    /**
     * encrypt
     *
     * @param string $value 需要加密的字符串
     * @return string 加密后的字符串
     */
    public function encrypt(string $value)
    {
        $td = mcrypt_module_open(MCRYPT_3DES, '', MCRYPT_MODE_CBC, '');
        $iv = base64_decode($this->iv);
        $value = $this->_paddingPKCS7($value);
        $key = base64_decode($this->key);
        mcrypt_generic_init($td, $key, $iv);
        $ret = base64_encode(mcrypt_generic($td, $value));
        mcrypt_generic_deinit($td);
        mcrypt_module_close($td);
        return $ret;
    }

    /**
     * decrypt
     *
     * @param string $value 需要解密的字符串
     * @return string 解密之后的字符串
     */
    public function decrypt(string $value)
    {
        $td = mcrypt_module_open(MCRYPT_3DES, '', MCRYPT_MODE_CBC, '');
        $iv = base64_decode($this->iv);
        $key = base64_decode($this->key);
        mcrypt_generic_init($td, $key, $iv);
        $ret = trim(mdecrypt_generic($td, base64_decode($value)));
        $ret = $this->_unpaddingPKCS7($ret);
        mcrypt_generic_deinit($td);
        mcrypt_module_close($td);
        return $ret;
    }

    /**
     * _paddingPKCS7
     */
    private function _paddingPKCS7($data)
    {
        $block_size = mcrypt_get_block_size('tripledes', 'cbc');
        $padding_char = $block_size - (strlen($data) % $block_size);
        $data .= str_repeat(chr($padding_char), $padding_char);
        return $data;
    }

    /**
     * _unpaddingPKCS7
     */
    private function _unpaddingPKCS7($text)
    {
        $pad = ord($text{strlen($text) - 1});
        if ($pad > strlen($text)) {
            return false;
        }
        if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) {
            return false;
        }
        return substr($text, 0, -1 * $pad);
    }
}